package com.czy.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.ValueNode;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;

/**
 * @author chenzy
 * @since 2020-10-14
 */
public class ObjectUtil {
    private ObjectUtil(){}

    /**
     * 判断参数2中是否存在等于参数1的对象
     */
    public static boolean equalOr(Object o,Object... compares) {
        return Arrays.stream(compares).anyMatch(temp-> equals(o,temp));
    }
    public static boolean equals(Object a, Object b) {
        if (a==b){
            return true;
        }
        if (a==null||b==null){
            return false;
        }
        return  a.equals(b);
    }


    public static <T> int getSize(T data){
        if (data==null){
            return 0;
        }
        if (data instanceof Map){
            return ((Map<?, ?>) data).size();
        }
        if (data instanceof Collection){
            return ((Collection<?>) data).size();
        }
        if (data instanceof String){
            return ((String) data).length();
        }
        if (data instanceof ValueNode){
            return ((ValueNode) data).size();
        }
        if (data instanceof JsonNode){
            return ((JsonNode) data).size();
        }
        if (data instanceof int[]){
            return ((int[]) data).length;
        }
        return String.valueOf(data).length();
    }
    public static <T> Boolean isEmpty(T data) {
        if (data==null){
            return true;
        }
        if (data instanceof Map){
            return ((Map<?, ?>) data).isEmpty();
        }
        if (data instanceof Collection){
            return ((Collection<?>) data).isEmpty();
        }
        if (data instanceof String){
            return StringUtil.isBlank((String) data);
        }
        if (data instanceof NumericNode){
            return true;
        }
        if (data instanceof JsonNode){
            return ((JsonNode) data).isEmpty();
        }
        return false;
    }
    public static <T> Boolean isNotEmpty(T data){
        return !isEmpty(data);

    }
    public static Boolean isEmptyOr(Object... dataList){
        if (ListUtil.isEmpty(dataList)) {
            return true;
        }
        return Arrays.stream(dataList).anyMatch(ObjectUtil::isEmpty);
    }


    public static <E extends Throwable> void emptyThrow(Supplier<? extends E> throwSupplier,Object... dataList) throws E {
        if (isEmptyOr(dataList)) {
            throw throwSupplier.get();
        }
    }

    public static boolean isEmptyAnd(Object... dataList) {
        if (ListUtil.isEmpty(dataList)) {
            return true;
        }
        return Arrays.stream(dataList).allMatch(ObjectUtil::isEmpty);
    }

    public static boolean isNotEmptyOr(Object... dataList) {
        if (ListUtil.isEmpty(dataList)) {
            return false;
        }
        return Arrays.stream(dataList).anyMatch(ObjectUtil::isNotEmpty);
    }
    public static boolean isNotEmptyAnd(Object... dataList) {
        if (ListUtil.isEmpty(dataList)) {
            return false;
        }
        return Arrays.stream(dataList).noneMatch(ObjectUtil::isEmpty);
    }

    /*参数要么都有值，要么都没值*/
    public static boolean yesOrNo(Object... dataList) {
        if (ListUtil.isEmpty(dataList)) {
            return true;
        }
        var yes=true;
        var no=true;
        for (var item:dataList){
            if (item instanceof String){
                if (StringUtil.isBlank((String) item)){
                    yes=false;
                }else {
                    no=false;
                }
            }else {
                if (item==null){
                    yes=false;
                }else {
                    no=false;
                }
            }
        }
        return yes||no;
    }


    /*两个参数 有一个为空时返回true。都为空或者都不为空时返回false */
    public static boolean isEmptyXor(Object o1, Object o2) {
        return isEmpty(o1)^isEmpty(o2);
    }
}
